<script setup lang="tsx">
import { ElTable, ElTableColumn, ElTabPane, ElTabs } from 'element-plus'
import { cronUtils } from 'fetm-utils'
import { computed, ref, unref, watch } from 'vue'
import Day from './component/Day.vue'
import Hour from './component/Hour.vue'
import Month from './component/Month.vue'
import SecondAndMinute from './component/SecondAndMinute.vue'
import Week from './component/Week.vue'
import Year from './component/Year.vue'

defineOptions({
  name: 'Cron',
})

const props = withDefaults(defineProps<{
  // 表达式位数 6 或 7，默认为 6 位表达式
  digits?: number
}>(), {
  digits: 6,
})

const modelValue = defineModel<string>('modelValue')

const activeName = ref('s')
const sVal = ref<string>()
const mVal = ref<string>()
const hVal = ref<string>()
const dVal = ref<string>()
const monthVal = ref<string>()
const weekVal = ref<string>()
const yearVal = ref<string>()
// 中文译文
const cronCn = ref<string>()

if (modelValue.value) {
  const arrays = modelValue.value.split(' ')
  sVal.value = arrays[0]
  mVal.value = arrays[1]
  hVal.value = arrays[2]
  dVal.value = arrays[3]
  monthVal.value = arrays[4]
  weekVal.value = arrays[5]
  yearVal.value = arrays[6]
}

watch(
  modelValue,
  (val) => {
    cronCn.value = cronUtils.cronParserToCn(val)
  },
  {
    immediate: true,
  },
)

const value = computed(() => {
  if (props.digits == 7) {
    const val = `${sVal.value} ${mVal.value} ${hVal.value} ${dVal.value} ${monthVal.value} ${weekVal.value} ${yearVal.value}`
    return val
  }
  else {
    const val = `${sVal.value} ${mVal.value} ${hVal.value} ${dVal.value} ${monthVal.value} ${weekVal.value}`
    return val
  }
})

watch(value, (val) => {
  if (modelValue.value != val)
    modelValue.value = val
})

const tableData = computed(() => {
  return [
    {
      sVal: sVal.value,
      mVal: mVal.value,
      hVal: hVal.value,
      dVal: dVal.value,
      monthVal: monthVal.value,
      weekVal: weekVal.value,
      yearVal: yearVal.value,
    },
  ]
})

function validate(digits: number = 6) {
  return new Promise<string>((resolve, reject) => {
    const isOk = cronUtils.cronCheck(unref(value), digits)
    if (!isOk)
      reject(new Error('表达式不合法'))
    if (dVal.value === '?' && weekVal.value === '?')
      reject(new Error('日期与星期不可以同时为“不指定”'))

    if (dVal.value !== '?' && weekVal.value !== '?')
      reject(new Error('日期与星期必须有一个为“不指定”'))

    resolve(unref(value))
  })
}

defineExpose({
  validate,
})
</script>

<template>
  <div class="cron border-(1px #dcdfe6 solid) p-10px" :val="value">
    <ElTabs v-model="activeName">
      <ElTabPane label="秒" name="s">
        <SecondAndMinute v-model="sVal" lable="秒" />
      </ElTabPane>
      <ElTabPane label="分" name="m">
        <SecondAndMinute v-model="mVal" lable="分" />
      </ElTabPane>
      <ElTabPane label="时" name="h">
        <Hour v-model="hVal" lable="时" />
      </ElTabPane>
      <ElTabPane label="日" name="d">
        <Day v-model="dVal" lable="日" />
      </ElTabPane>
      <ElTabPane label="月" name="month">
        <Month v-model="monthVal" lable="月" />
      </ElTabPane>
      <ElTabPane label="周" name="week">
        <Week v-model="weekVal" lable="周" />
      </ElTabPane>
      <ElTabPane v-if="digits == 7" label="年" name="year">
        <Year v-model="yearVal" lable="年" />
      </ElTabPane>
    </ElTabs>

    <!-- table -->
    <ElTable :data="tableData" size="small" border style="width: 100%">
      <ElTableColumn prop="sVal" label="秒" width="70" />
      <ElTableColumn prop="mVal" label="分" width="70" />
      <ElTableColumn prop="hVal" label="时" width="70" />
      <ElTableColumn prop="dVal" label="日" width="70" />
      <ElTableColumn prop="monthVal" label="月" width="70" />
      <ElTableColumn prop="weekVal" label="周" width="70" />
      <ElTableColumn v-if="digits == 7" prop="yearVal" label="年" />
    </ElTable>
    <div class="mt-10px line-height-30px">
      {{ cronCn }}
    </div>
  </div>
</template>
